/*
 * Copyright (C) 2009 Leandro Aparecido <lehphyro@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.metalframework.tracing.impl;

import java.lang.reflect.*;
import java.util.*;

import org.apache.commons.lang.*;
import org.metalframework.annotation.*;
import org.metalframework.tracing.*;
import org.metalframework.util.*;

@InfrastructureComponent
public class TraceParserDefaultImpl implements TraceParser {

	public TracingParameters parse(Method method) {
		TracingParameters parameters;
		
		Trace annotation = AnnotationUtils.getAnnotation(method.getDeclaringClass(), Trace.class);
		if (annotation == null) {
			annotation = AnnotationUtils.getAnnotation(method, Trace.class);
			if (annotation == null) {
				parameters = null;
			} else {
				parameters = new TracingParameters();
				parseAnnotation(annotation, parameters);
			}
		} else {
			parameters = new TracingParameters();
			parseAnnotation(annotation, parameters);
			
			annotation = AnnotationUtils.getAnnotation(method, Trace.class);
			if (annotation != null) {
				parseAnnotation(annotation, parameters);
			}
		}
		
		return parameters;
	}

	protected void parseAnnotation(Trace annotation, TracingParameters parameters) {
		parameters.setEnabled(annotation.enabled());
		parameters.setLogGetMethods(annotation.logGetMethods());
		parameters.setLogSetMethods(annotation.logSetMethods());
		parameters.setLogObjectMethods(annotation.logObjectMethods());
		parameters.setLevel(annotation.level());
		
		if (!StringUtils.isBlank(annotation.before())) {
			parameters.setBefore(annotation.before());
		}
		if (!StringUtils.isBlank(annotation.after())) {
			parameters.setAfter(annotation.after());
		}

		Locale locale;
		if (StringUtils.isBlank(annotation.locale())) {
			locale = Locale.getDefault();
		} else {
			String[] splitted = StringUtils.split(annotation.locale(), "_", 3);
			splitted = Arrays.copyOf(splitted, 3);
			if (splitted[2] != null) {
				locale = new Locale(splitted[0], splitted[1], splitted[2]);
			} else if (splitted[1] != null) {
				locale = new Locale(splitted[0], splitted[1]);
			} else {
				locale = new Locale(splitted[0]);
			}
		}
		parameters.setLocale(locale);
		
		for (Class<? extends Throwable> klass : annotation.logFor()) {
			parameters.addLogFor(klass);
		}
		for (Class<? extends Throwable> klass : annotation.noLogFor()) {
			parameters.addNoLogFor(klass);
		}
	}
}
